<?php

declare(strict_types=1);
/**
 * Author: Zane
 * Email: 873934580@qq.com
 * Date: 2023/5/26.
 */

namespace App\Http\Controllers\System;

use App\Exceptions\CommonExceptionConstants;
use App\Exceptions\ServiceException;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Traits\EditTrait;
use App\Http\Controllers\Traits\ExtendTrait;
use App\Http\Controllers\Traits\IndexTrait;
use App\Http\Controllers\Traits\StoreTrait;
use App\Http\Controllers\Traits\ValidateTrait;
use App\Models\Role;
use App\Service\PermissionService;
use App\Utils\ResultsVo;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Permission;

class RoleController extends Controller
{
    use EditTrait;
    use ExtendTrait;
    use IndexTrait;
    use StoreTrait;
    use ValidateTrait;

    protected $permissionService;

    public function __construct(PermissionService $permissionService)
    {
        parent::__construct();
        $this->permissionService = $permissionService;
    }

    public function before($data)
    {
        $data['guard_name'] = config('auth.app_guard_name');

        return $data;
    }

    /**
     * 角色设置权限.
     *
     * @param mixed   $id
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function setPermission($id, Request $request): \Illuminate\Http\JsonResponse
    {
        $ids = $request->get('ids');
        $role = Role::query()->find($id);
        if (!$role) {
            throw new ServiceException(CommonExceptionConstants::NO_FIND_DATA);
        }
        if (blank($ids)) {
            $role->permissions()->detach();

            return ResultsVo::success();
        }
        $permission = Permission::query()->whereIn('id', $ids)->get();
        $role->syncPermissions(data_get($permission->toArray(), '*.id'));

        return ResultsVo::success();
    }

    /**
     * 获取权限列表.
     *
     * @param mixed $id
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPermission($id): \Illuminate\Http\JsonResponse
    {
        $permission = $this->permissionService->getLabel();
        $role = Role::findById((int) $id, config('auth.app_guard_name'));
        $results = $checked = $data = [];
        infiniteLevel($permission, $data);
        foreach ($data as $item) {
            $results[] = $item;
            if ($role->hasPermissionTo($item['name'])) {
                $checked[] = $item['id'];
            }
        }

        $result = [
            'checked' => $checked,
            'results' => infiniteTree($results),
        ];

        return ResultsVo::success($result);
    }
}
